<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>建造者模式(生成器模式)-ES5</title>
</head>
<body>
    
</body>
<script>
    // 建造者模式(生成器模式)
    // 建造者模式用于：分步构建一个复杂对象 构建层与表示层分离
    // 若不是极其复杂的对象 应选择使用工厂模式等方式创建对象

    // 实现原理:
    // 通常使用链式调用来进行建造过程，最后调用build()方法生成最终对象

    // 建造者模式的优缺点
    // 优点:
        // 1.封装性好，创建和使用分离
        // 2.扩展性好，建造类之间独立、一定程度上解耦
    // 缺点:
        // 1.生成多余的Builder对象
        // 2.产品内部发生变化，建造者都要修改，成本较大
    
    // 建造者模式适用场景：
        // 相同的方法，不同的执行顺序，产生不一样的产品时，可以采用建造者模式
        // 产品的组成部件类似，通过组装不同的组件获得不同产品时，可以采用建造者模式

    // 建造者模式与工厂模式的区别：
        // 工厂模式关注的是创建的结果
        // 建造者模式不仅得到了结果，同时也参与了创建的具体过程

    // 建造者
    function CarBuilder({ color='white',weight=0}){
        this.color=color
        this.weight=weight
    }
    CarBuilder.prototype.buildType=function(type){
        switch (type){
            case 'small':
                this.tyreType='小号轮胎'
                this.tyreIntro='正在使用小号轮胎'
                break
            case 'normal':
                this.tyreType='中号轮胎'
                this.tyreIntro='正在使用中号轮胎'
                break
            case 'big':
                this.tyreType='大号轮胎'
                this.tyreIntro='正在使用大号轮胎'
                break
        }
    }
    CarBuilder.prototype.buildEngine = function(type){
        switch (type) {
            case 'small':
                this.engineType = '小马力发动机'
                this.engineIntro = '正在使用小马力发动机'
                break
            case 'normal':
                this.engineType = '中马力发动机'
                this.engineIntro = '正在使用中马力发动机'
                break
            case 'big':
                this.engineType = '大马力发动机'
                this.engineIntro = '正在使用大马力发动机'
                break
        }
    }

    function benChiDirector(tyre,engine,params){
        var car=new CarBuilder(params)
        car.buildType(tyre)
        car.buildEngine(engine)
        return car
    }

    var benchi= benChiDirector('small','big',{color:'black',weight:'1600KG'})
    console.log(benchi)
</script>
</html>